import { YFnObj, YFnParams, YItemConfig } from '../../interface';
function bindHandler(
  config: YItemConfig,
  mergeData: { [key: string]: any },
  handler?: (
    params: { [key: string]: any },
    mergeData: { [key: string]: any }
  ) => { [key: string]: any }
) {
  const value = config.bind || {};
  return (options: YFnParams) => {
    const result = typeof value === 'function' ? value(options) : value;
    return handler ? handler(result, mergeData) : { ...result, ...mergeData };
  };
}

const interception: {
  itemConfig?: { [key: string]: (config: YItemConfig) => YItemConfig };
  validate?: (form: any, callback: (isValid: boolean) => void) => void;
  event?: Function;
  get?: (vm: any, prop: string, value: any, config: any) => any;
  set?: (vm: any, prop: string, value: any, config: any) => any;
  props?: (props: { [key: string]: any }, vm: any) => { [key: string]: any };
  rule?: (rule: any, form: any) => any;
} = {
  itemConfig: {
    '*'(config: YItemConfig) {
      return config;
    },
    select(config) {
      if (!config.dictionaryName) {
        config.optionType = undefined;
      }
      return config;
    },
    radioGroup(config) {
      if (config.optionType === 'radioButton') {
        config.bind = bindHandler(config, { type: 'button' });
      }
      config.optionHandler = (options: { [key: string]: any }[]) => {
        return options.map((option) => {
          return {
            type: 'radio',
            bind: {
              ...option,
            },
            nodes: option.label,
          };
        });
      };
      return config;
    },
    checkboxGroup(config) {
      config.optionType = undefined;
      config.optionHandler = (options: { [key: string]: any }[]) => {
        return options.map((option) => {
          return {
            type: 'checkbox',
            bind: option,
            nodes: option.label,
          };
        });
      };
      return config;
    },
    checkbox(config) {
      config.bind = bindHandler(config, {});
      config.nodes =
        'nodes' in config
          ? config.nodes
          : (options: YFnParams) => {
              const bind = (config.bind as YFnObj)(options);
              return bind.label;
            };
      return config;
    },
    treeSelect(config) {
      config.bind = bindHandler(config, {
        fieldNames: { title: 'label', key: 'value' },
      });
      return config;
    },
    dateTime(config) {
      config.bind = bindHandler(config, { showTime: true });
      return config;
    },
    weekRange(config) {
      config.bind = bindHandler(config, { mode: 'week' });
      return config;
    },
    monthRange(config) {
      config.bind = bindHandler(config, { mode: 'month' });
      return config;
    },
    yearRange(config) {
      config.bind = bindHandler(config, { mode: 'year' });
      return config;
    },
    dateTimeRange(config) {
      config.bind = bindHandler(config, { showTime: true });
      return config;
    },
  },
  validate(form: any, callback: (isValid: boolean) => void) {
    form.validate().then((result: any) => {
      callback && callback(!result);
    });
  },
  props(props) {
    const labelPosition = props.labelPosition;
    if (labelPosition) {
      props.labelPosition = undefined;
      if (labelPosition !== 'top') {
        props.labelAlign = labelPosition;
      } else {
        props.layout = 'vertical';
      }
    }
    return props;
  },
};

export default interception;
